-- Lua Battle System - 角色系统基础单元测试

-- 设置Lua路径
package.path = package.path .. ';src/?.lua;src/utils/?.lua;src/characters/?.lua;res/data/?.lua'

local TestFramework = require("src.utils.test_framework")
local Logger = require("utils.logger")
local Character = require("characters.character")

local function run_tests()
    local suite = TestFramework.create_suite("Character Basic Unit Tests")

    -- 测试套件设置
    local function setup()
        -- 设置日志级别为debug以查看更多输出
        Logger.init({level = "debug"})
    end

    local function teardown()
        -- 清理测试环境
    end

    suite:setup(setup)
    suite:teardown(teardown)

    -- 测试1：Character模块加载
    suite:add_test("Character module loading", function()
        TestFramework.Assert.is_type("table", Character, "Character should be a table")
        TestFramework.Assert.is_type("function", Character.new, "Character.new should be a function")
    end)

    -- 测试2：角色创建和基本属性
    suite:add_test("Character creation and basic attributes", function()
        local character_data = {
            id = "test_character_001",
            name = "Test Character",
            level = 5,
            max_hp = 150,
            hp = 150,
            max_mp = 80,
            mp = 80,
            attack = 25,
            defense = 12,
            magic_attack = 18,
            magic_defense = 10,
            speed = 20,
            luck = 12
        }

        local character = Character:new(character_data)

        TestFramework.Assert.is_not_nil(character, "Character should be created successfully")
        TestFramework.Assert.equals("test_character_001", character.id, "Character ID should match")
        TestFramework.Assert.equals("Test Character", character.name, "Character name should match")
        TestFramework.Assert.equals(5, character.level, "Character level should match")
        TestFramework.Assert.equals(150, character.max_hp, "Character max HP should match")
        TestFramework.Assert.equals(80, character.max_mp, "Character max MP should match")
        TestFramework.Assert.equals(25, character.attack, "Character attack should match")
        TestFramework.Assert.equals(12, character.defense, "Character defense should match")
        TestFramework.Assert.is_true(character.is_alive, "Character should be alive initially")
    end)

    -- 测试3：默认属性值
    suite:add_test("Character default attributes", function()
        local character = Character:new()

        TestFramework.Assert.equals("", character.id, "Default ID should be empty string")
        TestFramework.Assert.equals("", character.name, "Default name should be empty string")
        TestFramework.Assert.equals(1, character.level, "Default level should be 1")
        TestFramework.Assert.equals(100, character.max_hp, "Default max HP should be 100")
        TestFramework.Assert.equals(100, character.hp, "Default HP should be 100")
        TestFramework.Assert.equals(50, character.max_mp, "Default max MP should be 50")
        TestFramework.Assert.equals(50, character.mp, "Default MP should be 50")
        TestFramework.Assert.equals(20, character.attack, "Default attack should be 20")
        TestFramework.Assert.equals(10, character.defense, "Default defense should be 10")
        TestFramework.Assert.is_true(character.is_alive, "Default is_alive should be true")
    end)

    -- 测试4：伤害和治疗功能
    suite:add_test("Damage and healing functions", function()
        local character = Character:new({
            id = "test_character",
            name = "Test",
            max_hp = 200,
            hp = 200,
            defense = 20
        })

        local initial_hp = character.hp

        -- 测试受到伤害
        local damage_taken = character:take_damage(50)
        TestFramework.Assert.is_true(damage_taken > 0, "Damage taken should be positive")
        TestFramework.Assert.is_true(character.hp < initial_hp, "HP should decrease after damage")

        -- 测试治疗
        local heal_amount = 30
        local actual_heal = character:heal(heal_amount)
        TestFramework.Assert.equals(heal_amount, actual_heal, "Heal amount should match")
        TestFramework.Assert.is_true(character.hp > (initial_hp - damage_taken), "HP should increase after heal")

        -- 测试治疗不超过最大值
        character:heal(1000)  -- 超大治疗量
        TestFramework.Assert.equals(character.max_hp, character.hp, "HP should not exceed max HP")
    end)

    -- 测试5：魔法值管理
    suite:add_test("Magic points management", function()
        local character = Character:new({
            id = "test_character",
            name = "Test",
            max_mp = 100,
            mp = 80
        })

        -- 测试消耗魔法值
        local mp_consumed = 20
        local consume_result = character:consume_mp(mp_consumed)
        TestFramework.Assert.is_true(consume_result, "Should successfully consume MP when enough")
        TestFramework.Assert.equals(60, character.mp, "MP should decrease after consumption")

        -- 测试魔法值不足
        local consume_result = character:consume_mp(100)
        TestFramework.Assert.is_false(consume_result, "Should fail to consume MP when not enough")
        TestFramework.Assert.equals(60, character.mp, "MP should remain unchanged when consumption fails")

        -- 测试恢复魔法值
        local mp_recovered = character:recover_mp(30)
        TestFramework.Assert.equals(30, mp_recovered, "Should recover specified amount")
        TestFramework.Assert.equals(90, character.mp, "MP should increase after recovery")

        -- 测试恢复不超过最大值
        character:recover_mp(100)  -- 超大恢复量
        TestFramework.Assert.equals(character.max_mp, character.mp, "MP should not exceed max MP")
    end)

    -- 测试6：生命状态管理
    suite:add_test("Life status management", function()
        local character = Character:new({
            id = "test_character",
            name = "Test",
            max_hp = 100,
            hp = 100
        })

        TestFramework.Assert.is_true(character.is_alive, "Character should be alive initially")

        -- 测试致命伤害
        character:take_damage(200)  -- 超过当前HP的伤害
        TestFramework.Assert.equals(0, character.hp, "HP should be 0 after fatal damage")
        TestFramework.Assert.is_false(character.is_alive, "Character should be dead after fatal damage")
    end)

    -- 测试7：当前属性获取
    suite:add_test("Current stats retrieval", function()
        local character = Character:new({
            id = "test_character",
            name = "Test",
            attack = 30,
            defense = 15,
            magic_attack = 25,
            magic_defense = 10,
            speed = 20,
            luck = 8
        })

        local stats = character:get_current_stats()

        TestFramework.Assert.is_type("table", stats, "get_current_stats should return a table")
        TestFramework.Assert.equals(character.hp, stats.hp, "Current HP should match")
        TestFramework.Assert.equals(character.mp, stats.mp, "Current MP should match")
        TestFramework.Assert.equals(character.attack, stats.attack, "Attack should match")
        TestFramework.Assert.equals(character.defense, stats.defense, "Defense should match")
        TestFramework.Assert.equals(character.magic_attack, stats.magic_attack, "Magic attack should match")
        TestFramework.Assert.equals(character.magic_defense, stats.magic_defense, "Magic defense should match")
        TestFramework.Assert.equals(character.speed, stats.speed, "Speed should match")
        TestFramework.Assert.equals(character.luck, stats.luck, "Luck should match")
    end)

    -- 测试8：状态效果基础功能
    suite:add_test("Status effects basic functionality", function()
        local character = Character:new({
            id = "test_character",
            name = "Test"
        })

        -- 创建模拟状态效果
        local status_effect = {
            id = "test_effect",
            name = "Test Effect",
            duration = 3
        }

        -- 测试添加状态效果
        character:add_status_effect(status_effect)

        -- 验证状态效果已添加（通过检查status_effects表）
        TestFramework.Assert.is_not_nil(character.status_effects.test_effect, "Status effect should be added")
        TestFramework.Assert.equals("Test Effect", character.status_effects.test_effect.name, "Status effect name should match")

        -- 测试移除状态效果
        character:remove_status_effect("test_effect")
        TestFramework.Assert.is_nil(character.status_effects.test_effect, "Status effect should be removed")
    end)

    -- 测试9：装备系统基础
    suite:add_test("Equipment system basics", function()
        local character = Character:new({
            id = "test_character",
            name = "Test"
        })

        -- 验证装备槽位存在
        TestFramework.Assert.is_type("table", character.equipment, "Equipment should be a table")
        TestFramework.Assert.is_nil(character.equipment.weapon, "Weapon slot should be empty initially")
        TestFramework.Assert.is_nil(character.equipment.armor, "Armor slot should be empty initially")
        TestFramework.Assert.is_nil(character.equipment.accessory, "Accessory slot should be empty initially")
    end)

    -- 运行测试套件
    suite:run()

    -- 返回测试结果
    return TestFramework.get_stats().failed == 0
end

-- 导出测试函数
return {
    run_tests = run_tests
}